package main

import (
	"fmt"
	"time"
)

func worker(id int, c chan int) {
	//for {
	//	//n := <-c
	//	n, ok := <-c
	//	if !ok {
	//		break
	//	}
	//	fmt.Printf("worker %d received %c \n", id, n)
	//}

	for n := range c {
		fmt.Printf("worker %d received %c \n", id, n)
	}
}

func createWorker(id int) chan<- int {
	c := make(chan int)
	go func() {
		for {
			//n := <-c
			fmt.Printf("worker %d received %c \n", id, <-c)
		}
	}()
	return c
}

func chanDemo1() {
	//var c chan int  //c==nil
	c := make(chan int)
	go worker(0, c)
	c <- 'a'
	c <- 'b'
	time.Sleep(time.Millisecond)

}

func chanDemo2() {

	var channels [10]chan int
	for i := 0; i < 10; i++ {
		channels[i] = make(chan int)
		go worker(i, channels[i])
	}

	for i := 0; i < 10; i++ {
		channels[i] <- 'a' + i
	}

	for i := 0; i < 10; i++ {
		channels[i] <- 'A' + i
	}

	time.Sleep(time.Millisecond)

}

func chanDemo3() {

	var channels [10]chan<- int
	for i := 0; i < 10; i++ {
		channels[i] = createWorker(i)
	}

	for i := 0; i < 10; i++ {
		channels[i] <- 'a' + i
	}

	for i := 0; i < 10; i++ {
		channels[i] <- 'A' + i
	}

	time.Sleep(time.Millisecond)

}

func bufferedChannel() {
	c := make(chan int, 3)
	go worker(0, c)
	c <- 'a' + 1
	c <- 'a' + 2
	c <- 'a' + 3
	c <- 'a' + 4
	time.Sleep(time.Millisecond)
}

//channel是可以close的。
//注意：如果需要close，那么永远是发送方close
func channelClose() {
	c := make(chan int)
	go worker(0, c)
	c <- 'a'
	c <- 'b'
	c <- 'c'
	c <- 'd'
	close(c)
	time.Sleep(time.Millisecond)
}

func main() {
	//fmt.Println("简单使用channel")
	//chanDemo1()
	//fmt.Println("Channel as first-class citizen")
	//chanDemo2()
	//chanDemo3()
	//fmt.Println("Buffered channel")
	//bufferedChannel()
	//fmt.Println("Channel close and range")
	//channelClose()
}
